package cn.fastoo.common.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilderFactory;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * http请求GET和 POST工具类
 *
 * @author Even Chan
 *
 */
public class HttpRequestUtils {
    // 默认连接超时时间：毫秒
    private final static int DEFAULT_CONNE_CTTIMEOUT = 3000;
    // 默认读取超时时间：毫秒
    private final static int DEFAULT_READ_CTTIMEOUT = 3000;

    /**
     * get请求
     *
     * @param url
     * @return
     * @throws IOException
     */
    public static String readContentFromGet(String url) throws IOException {
        URL getUrl = new URL(url);
        // 根据拼凑的URL,打开连接,URL.openConnection()函数会根据URL的类型，返回不同的URLConnection子类的对象,在这里我们的URL是一个http，因此它实际上返回的是HttpURLConnection
        HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
        // 建立与服务器的连接，并未发送数据
        connection.setConnectTimeout(3000);
        connection.setReadTimeout(3000);
        connection.connect();
        // 发送数据到服务器并使用Reader读取返回的数据
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String lines;
        StringBuilder sb = new StringBuilder();
        while ((lines = reader.readLine()) != null) {
            sb.append(lines);
        }
        reader.close();
        // 断开连接
        connection.disconnect();
        return sb.toString();
    }

    /**
     * get请求
     *
     * @param url
     * @return
     * @throws IOException
     */
    public static String readContentFromPost(String url,Map<String, String> params) throws IOException {
        HttpClient httpClient = new DefaultHttpClient();

        HttpPost httpPost = new HttpPost(url);

        httpPost.setHeader("Content-Type","application/x-www-form-urlencoded");

        List<BasicNameValuePair> paramList = new ArrayList<BasicNameValuePair>();
        for (String key:params.keySet()) {
            paramList.add(new BasicNameValuePair(key,params.get(key)));
        }
        try{
            httpPost.setEntity(new UrlEncodedFormEntity(paramList,"UTF-8"));
        }catch (Exception e) {}

        HttpResponse response = null;
        String temp="";
        try{
            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            temp= EntityUtils.toString(entity,"UTF-8");
        }catch (Exception e) {}

        return temp;
    }

    /**
     * get请求
     *
     * @param url
     * @return
     * @throws IOException
     */
    public static String readContentFromPost(String url,String contentType,Map<String, String> params) throws IOException {
        HttpClient httpClient = new DefaultHttpClient();

        HttpPost httpPost = new HttpPost(url);

        httpPost.setHeader("Content-Type",contentType);

        List<BasicNameValuePair> paramList = new ArrayList<BasicNameValuePair>();
        for (String key:params.keySet()) {
            paramList.add(new BasicNameValuePair(key,params.get(key)));
        }
        try{
            httpPost.setEntity(new UrlEncodedFormEntity(paramList,"UTF-8"));
        }catch (Exception e) {}

        HttpResponse response = null;
        String temp="";
        try{
            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            temp= EntityUtils.toString(entity,"UTF-8");
        }catch (Exception e) {}

        return temp;
    }

    public static String readXMLContentFromGet(String url) throws Exception {
        URL getUrl = new URL(url);
        String result = null;
        // 根据拼凑的URL,打开连接,URL.openConnection()函数会根据URL的类型，返回不同的URLConnection子类的对象,在这里我们的URL是一个http，因此它实际上返回的是HttpURLConnection
        HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
        // 建立与服务器的连接，并未发送数据
        connection.setConnectTimeout(3000);
        connection.setReadTimeout(3000);
        connection.connect();
        // 发送数据到服务器并使用Reader读取返回的数据
        Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(connection.getInputStream());
        return document.getFirstChild().getFirstChild().getTextContent();
    }

    public static JSONObject readXMLContentFromGetParseJSON(String url) throws Exception {
        String result = readXMLContentFromGet(url);
        return JSONObject.parseObject( result);
    }

    /**
     * get请求，读取内容为utf-8编码
     *
     * @param url
     * @return
     * @throws IOException
     */
    public static String readContentFromGetOfUTF8(String url) throws IOException {
        URL getUrl = new URL(url);
        // 根据拼凑的URL,打开连接,URL.openConnection()函数会根据URL的类型，返回不同的URLConnection子类的对象,在这里我们的URL是一个http，因此它实际上返回的是HttpURLConnection
        HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
        // 建立与服务器的连接，并未发送数据
        connection.setConnectTimeout(DEFAULT_CONNE_CTTIMEOUT);
        connection.setReadTimeout(DEFAULT_READ_CTTIMEOUT);
        connection.connect();
        // 发送数据到服务器并使用Reader读取返回的数据
        StringBuilder sb = new StringBuilder();
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        String line;
        // 读取返回的内容
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
        in.close();
        // 断开连接
        connection.disconnect();
        return sb.toString();
    }

    /**
     * get请求，读取内容为gb1312编码
     *
     * @param url
     * @return
     * @throws IOException
     */
    public static String readContentFromGetOfGB2312(String url) throws IOException {
        URL getUrl = new URL(url);
        // 根据拼凑的URL,打开连接,URL.openConnection()函数会根据URL的类型，返回不同的URLConnection子类的对象,在这里我们的URL是一个http，因此它实际上返回的是HttpURLConnection
        HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
        // 建立与服务器的连接，并未发送数据
        connection.setConnectTimeout(DEFAULT_CONNE_CTTIMEOUT);
        connection.setReadTimeout(DEFAULT_READ_CTTIMEOUT);
        connection.connect();
        // 发送数据到服务器并使用Reader读取返回的数据
        StringBuilder sb = new StringBuilder();
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "GB2312"));
        String line;
        // 读取返回的内容
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
        in.close();
        // 断开连接
        connection.disconnect();
        return sb.toString();
    }

    /**
     * post请求
     *
     * @param url
     * @param content
     * @return
     * @throws IOException
     */
    public static String readContentFromPost(String url, String content) throws IOException {
        URL postUrl = new URL(url);
        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
        // 打开读写属性，默认均为false
        connection.setDoOutput(true);
        connection.setDoInput(true);
        // 设置请求方式，默认为GET
        connection.setRequestMethod("POST");
        // Post 请求不能使用缓存
        connection.setUseCaches(false);
        connection.setInstanceFollowRedirects(true);
        connection.setConnectTimeout(DEFAULT_CONNE_CTTIMEOUT);
        connection.setReadTimeout(DEFAULT_READ_CTTIMEOUT);
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        out.writeBytes(content);
        out.flush();
        out.close();
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        reader.close();
        // 关闭连接
        connection.disconnect();
        return sb.toString();
    }

    /**
     * post请求
     *
     * @param url
     * @param content
     * @return
     * @throws IOException
     */
    public static String readContentFromPost(String url, String content,String charSet) throws IOException {
        URL postUrl = new URL(url);
        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
        // 打开读写属性，默认均为false
        connection.setDoOutput(true);
        connection.setDoInput(true);
        // 设置请求方式，默认为GET
        connection.setRequestMethod("POST");
        // Post 请求不能使用缓存
        connection.setUseCaches(false);
        connection.setInstanceFollowRedirects(true);
        connection.setConnectTimeout(DEFAULT_CONNE_CTTIMEOUT);
        connection.setReadTimeout(DEFAULT_READ_CTTIMEOUT);
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        out.writeBytes(content);
        out.flush();
        out.close();
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        reader.close();
        // 关闭连接
        connection.disconnect();
        return sb.toString();
    }

    /**
     * post请求，post域为json格式
     *
     * @param url
     * @param content
     * @return
     * @throws IOException
     */
    public static String readContentFromPostJson(String url, String content) throws IOException {
        URL postUrl = new URL(url);
        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("POST");
        connection.setUseCaches(false);
        connection.setInstanceFollowRedirects(true);
        //connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
        connection.addRequestProperty("Accept-Charset", "UTF-8");
        connection.setConnectTimeout(DEFAULT_CONNE_CTTIMEOUT);
        connection.setReadTimeout(DEFAULT_READ_CTTIMEOUT);
        PrintWriter out = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "utf-8"));
        out.println(content);
        out.flush();
        out.close();
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        reader.close();
        // 关闭连接
        connection.disconnect();
        return sb.toString();
    }

    /**
     * 从request 中获得 post数据
     * @param request
     * @return
     * @throws IOException
     */
    public static String readContentFormRequest (HttpServletRequest request) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while((line = br.readLine())!=null){
            sb.append(line);
        }
        br.close();
        return sb.toString();

    }

    /**
     * 从request 中获得 post数据的json数据并做解析
     * @param request
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public static <T> T readContentFormRequest (HttpServletRequest request,Class<T> jsonClass) throws IOException {
        String json = readContentFormRequest(request);
        if(StringUtils.isBlank(json)){
            throw new IOException();
        }
        return (T) JSONObject.parseObject(json, jsonClass);
    }

    /**
     * 从request 中获得 post数据的并转换为Json
     * @param request
     * @return
     * @throws IOException
     */
    public static JSONObject readContentFormRequestToJsonObj(HttpServletRequest request) throws IOException {
        String json = readContentFormRequest(request);
        if(StringUtils.isBlank(json)){
            throw new IOException();
        }
        return   JSONObject.parseObject(json);
    }


    public static byte[] getBytesFromNetByUrl(String strUrl){
        try {
            URL url = new URL(strUrl);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5 * 1000);
            InputStream inStream = conn.getInputStream();//通过输入流获取图片数据
            byte[] btImg = readInputStream(inStream);//得到图片的二进制数据
            return btImg;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public  static BufferedImage getBufferedImageFromUrl(String url){
        byte[] bytes = getBytesFromNetByUrl(url);
        if(bytes==null || bytes.length==0){
            return null;
        }
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);    //将b作为输入流；
        try {
            BufferedImage image = ImageIO.read(in);     //将in作为输入流，读取图片存入image中，而这里in可以为ByteArrayInputStream();
            return  image;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 从输入流中获取数据
     * @param inStream 输入流
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) throws Exception{
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while( (len=inStream.read(buffer)) != -1 ){
            outStream.write(buffer, 0, len);
        }
        inStream.close();
        return outStream.toByteArray();
    }


}